// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud

#if NO_SILVERLIGHT
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using BrainTechLLC.ThreadSafeObjects;

namespace BrainTechLLC.Communication
{
    /// <summary>
    /// Implements TCP/IP communication using the .NET Socket object
    /// </summary>
#if NO_SILVERLIGHT
    [Browsable(true)]
#endif
    public class TCPIPSocketProtocol : ICommunicationsProtocol
    {
        public int Available
        {
            get { return TcpClientConnection.Available; }
        }

        public Socket Socket
        {
            get { return TcpClientConnection; }
            set { TcpClientConnection = value; }
        }

        public Socket TcpClientConnection
        {
            get;
            set;
        }

        public void Close()
        {
            TcpClientConnection.Close();
        }

        /// <summary>
        /// Takes care of cleaning up a TcpClient connection - a bit messy, but functional.
        /// </summary>
        public void CloseAndCleanup()
        {
            if (TcpClientConnection != null)
            {
                try { TcpClientConnection.Shutdown(SocketShutdown.Both); }
                catch { }
                try { TcpClientConnection.Close(); }
                catch { }
                TcpClientConnection = null;
            }
        }

        public bool Connect(string hostName, int portNumber, bool wantThrowException)
        {
            Socket s = null;
            Socket tempSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                tempSocket.Connect(hostName, portNumber);

                if (tempSocket.Connected)
                {
                    s = tempSocket;
                }
                else
                {
                    s = null;
                }
            }
            catch { }

            TcpClientConnection = s;
            return (s != null);
        }

        public int Receive(byte[] buffer, int offset, int size, SocketFlags flags, out SocketError errorCode)
        {
            int bytes = TcpClientConnection.Receive(buffer, offset, size, flags, out errorCode);
            return bytes;
        }

        public int Send(byte[] buffer, int offset, int size, SocketFlags flags, out SocketError errorCode)
        {
            return TcpClientConnection.Send(buffer, offset, size, flags, out errorCode);
        }
    }
}
#endif
